<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  <title>springcloud之bus微服务消息总线 | rongshen</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  
  
  
<link rel="stylesheet" href="/css/style.css">

  
    
<link rel="stylesheet" href="/css/highlight.css">

  
  <meta name="description" content="springcloud学习笔记，第9章，Bus服务总线。">
<meta property="og:type" content="article">
<meta property="og:title" content="springcloud之bus微服务消息总线">
<meta property="og:url" content="http://example.com/2020/09/30/springcloud%E4%B9%8Bbus%E5%BE%AE%E6%9C%8D%E5%8A%A1%E6%B6%88%E6%81%AF%E6%80%BB%E7%BA%BF/index.html">
<meta property="og:site_name" content="rongshen">
<meta property="og:description" content="springcloud学习笔记，第9章，Bus服务总线。">
<meta property="og:locale" content="en_US">
<meta property="og:image" content="http://cdn.rongshen2020.com/2020930a1.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/2020930a2.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/2020930a3.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/2020930a4.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/2020930a5.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/2020930a6.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/2020930a7.png">
<meta property="og:image" content="http://cdn.rongshen2020.com/2020930a8.png">
<meta property="article:published_time" content="2020-09-30T07:40:09.000Z">
<meta property="article:modified_time" content="2021-05-07T06:49:25.879Z">
<meta property="article:author" content="John Doe">
<meta property="article:tag" content="springCloud">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="http://cdn.rongshen2020.com/2020930a1.png"><meta name="generator" content="Hexo 6.1.0"></head>

<body>
  <div id="wrapper">
    <header id="header">
  <h1 id="title">
    <a href="/">rongshen</a>
  </h1>
  <nav>
    
    
      
      <a class="nav-link" href="/">Home</a>
    
      
        <span class="nav-spacer">×</span>
      
      <a class="nav-link" href="/archives">Archives</a>
    
      
        <span class="nav-spacer">×</span>
      
      <a class="nav-link" target="_blank" rel="noopener" href="https://github.com/Aaron-boom">Github</a>
    
      
        <span class="nav-spacer">×</span>
      
      <a class="nav-link" href="/2020/04/13/About-Me/">About</a>
    
    
  </nav>
</header>

    <div id="content">
      <article id="post-springcloud之bus微服务消息总线" class="article article-type-post" itemprop="blogPost" itemscope>
  <div class="article-inner">
    
      <header class="article-header">
        
  
    <h2 class="article-title" itemprop="headline name">
      springcloud之bus微服务消息总线
    </h2>
  


        <div class="article-meta">
          <time class="article-date" datetime="2020-09-30T07:40:09.000Z" itemprop="datePublished">2020-09-30</time>

          
        </div>
      </header>
    
    <div class="article-entry" itemprop="articleBody">
      
      
        <blockquote>
<p>springcloud学习笔记，第9章，Bus服务总线。</p>
</blockquote>
<span id="more"></span>


<h2 id="概述："><a href="#概述：" class="headerlink" title="概述："></a>概述：</h2><p>我们前一章学习了config配置中心，需要去探索如何实现分布式自动刷新配置功能？spring cloud bus配合spring cloud config使用可实现配置的自动动态刷新。</p>
<p><strong>bus支持两种消息代理中间件：RabbitMQ和kafka</strong></p>
<p><strong>下面两张图实现原理并不同，注意看</strong></p>
<p>图一如下：利用消息总线触发一个客户端&#x2F;bus&#x2F;refresh，而刷新所有客户端的配置。</p>
<p><img src="http://cdn.rongshen2020.com/2020930a1.png"></p>
<p>springcloud bus能管理和传播分布式系统间的消息，就像一个分布式执行器，可用于广播状态更改、事件推送等，也可以当做微服务间的通信通道。</p>
<p>图二如下：利用消息总线触发一个服务端ConfigServer的&#x2F;bus&#x2F;refresh端点，而刷新所有客户端的配置。</p>
<p><img src="http://cdn.rongshen2020.com/2020930a2.png"></p>
<h3 id="为什么会被称为消息总线？"><a href="#为什么会被称为消息总线？" class="headerlink" title="为什么会被称为消息总线？"></a>为什么会被称为消息总线？</h3><p><img src="http://cdn.rongshen2020.com/2020930a3.png"></p>
<p>所以要结合消息中间件一起使用。</p>
<hr>
<h2 id="进行实例演示之前，需要先安装好RabbitMQ或kafka消息中间件，配置好环境。"><a href="#进行实例演示之前，需要先安装好RabbitMQ或kafka消息中间件，配置好环境。" class="headerlink" title="进行实例演示之前，需要先安装好RabbitMQ或kafka消息中间件，配置好环境。"></a><strong>进行实例演示之前，需要先安装好RabbitMQ或kafka消息中间件，配置好环境。</strong></h2><h2 id="springcloud-Bus动态刷新全局广播："><a href="#springcloud-Bus动态刷新全局广播：" class="headerlink" title="springcloud Bus动态刷新全局广播："></a>springcloud Bus动态刷新全局广播：</h2><h3 id="新建一个3366客户端模块："><a href="#新建一个3366客户端模块：" class="headerlink" title="新建一个3366客户端模块："></a>新建一个3366客户端模块：</h3><ol>
<li><p>新建模块，<code>cloud-config-client-3366</code></p>
</li>
<li><p>POM</p>
</li>
<li><p>bootstrap.yml</p>
</li>
<li><p>主启动</p>
</li>
<li><p>controller：</p>
<pre><code class="java">@RestController
@RefreshScope
public class ConfigClientController &#123;
    @Value(&quot;$&#123;config.info&#125;&quot;)
    private String configInfo;

    @Value(&quot;$&#123;server.port&#125;&quot;)
    private String serverPort;

    @GetMapping(&quot;/configInfo&quot;)
    public String getConfigInfo()&#123;
        return &quot;serverPort:&quot;+serverPort+&quot;\n&quot;+&quot;configInfo:&quot;+configInfo;
    &#125;
&#125;
</code></pre>
</li>
</ol>
<h3 id="设计思想："><a href="#设计思想：" class="headerlink" title="设计思想："></a>设计思想：</h3><p>之前的图一利用消息总线触发一个客户端&#x2F;bus&#x2F;refresh，而刷新所有客户端的配置。</p>
<p>图二利用消息总线触发一个服务端ConfigServer的&#x2F;bus&#x2F;refresh端点，而刷新所有客户端的配置。</p>
<p>图二的架构显然更加适合该动态刷新全局广播，图一不适合的原因如下：</p>
<p><img src="http://cdn.rongshen2020.com/2020930a4.png"></p>
<h3 id="给cloud-config-center-3344配置中心服务端添加消息总线支持："><a href="#给cloud-config-center-3344配置中心服务端添加消息总线支持：" class="headerlink" title="给cloud-config-center-3344配置中心服务端添加消息总线支持："></a>给cloud-config-center-3344配置中心服务端添加消息总线支持：</h3><ol>
<li><p>POM：</p>
<pre><code class="JAVA">&lt;!--添加消息总线RabbitMQ支持--&gt;
&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
    &lt;artifactId&gt;spring-cloud-starter-bus-amqp&lt;/artifactId&gt;
&lt;/dependency&gt;
</code></pre>
</li>
<li><p>YML：</p>
<pre><code class="JAVA"># rabbitMQ相关配置
rabbitmq:
  host: localhost
  port: 5672
  username: guest
  password: guest


# rabbitMQ相关配置，暴露bus刷新配置的端点
management:
  endpoints:
    web:
      exposure:
        include: &#39;bus-refresh&#39;
</code></pre>
<p><img src="http://cdn.rongshen2020.com/2020930a5.png"></p>
</li>
</ol>
<h3 id="给cloud-config-client-3355客户端添加消息总线支持："><a href="#给cloud-config-client-3355客户端添加消息总线支持：" class="headerlink" title="给cloud-config-client-3355客户端添加消息总线支持："></a>给cloud-config-client-3355客户端添加消息总线支持：</h3><ol>
<li><p>POM：</p>
<pre><code class="java">&lt;!--添加消息总线RabbitMQ支持--&gt;
&lt;dependency&gt;
    &lt;groupId&gt;org.springframework.cloud&lt;/groupId&gt;
    &lt;artifactId&gt;spring-cloud-starter-bus-amqp&lt;/artifactId&gt;
&lt;/dependency&gt;
</code></pre>
</li>
<li><p>YML：</p>
<pre><code class="java">rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest
</code></pre>
<p><img src="http://cdn.rongshen2020.com/2020930a6.png"></p>
</li>
</ol>
<h3 id="给cloud-config-client-3366客户端添加消息总线支持："><a href="#给cloud-config-client-3366客户端添加消息总线支持：" class="headerlink" title="给cloud-config-client-3366客户端添加消息总线支持："></a>给cloud-config-client-3366客户端添加消息总线支持：</h3><p>和3355一致。</p>
<h3 id="测试："><a href="#测试：" class="headerlink" title="测试："></a>测试：</h3><ol>
<li><p>修改github上的版本号，给3344发送<code>curl -X POST &quot;http://localhost:3344/actuator/bus-refresh&quot;</code></p>
<p><img src="http://cdn.rongshen2020.com/2020930a7.png"></p>
<p>就不用还给3355和3366发了。</p>
</li>
<li><p>浏览器测试：<code>http://localhost:3344/config-dev.yml</code></p>
</li>
<li><p>客户端测试：<code>http://localhost:3355/configInfo</code>和<code>http://localhost:3366/configInfo</code></p>
</li>
<li><p>获取配置，发现都已经刷新了。</p>
</li>
</ol>
<p><strong>实现一次修改、广播通知，处处生效。</strong></p>
<p>所以这里就是运维人员给3344推送一次刷新就可以实现全部的刷新。完美解决了config的动态刷新问题。</p>
<h2 id="springcloud-Bus动态刷新定点通知："><a href="#springcloud-Bus动态刷新定点通知：" class="headerlink" title="springcloud Bus动态刷新定点通知："></a>springcloud Bus动态刷新定点通知：</h2><p>要求：还是以上述实验为例，我们不想通知3366，只通知3355更新信息。</p>
<p><img src="http://cdn.rongshen2020.com/2020930a8.png"></p>
<p>那么上述的话实现就是：</p>
<pre><code class="java">curl -X POST &quot;http://localhost:3344/actuator/bus-refresh/config-client:3355&quot;
</code></pre>
<p><strong>下一篇博客讲解stream消息驱动模块，见！</strong></p>

      
    </div>
    
    
    <div class="article-category">
      
        <b>Categories:</b>
        <a class="article-category-link" href="/categories/spring-cloud/">spring cloud</a>
      
      
        <br/>
      
      
        <b>Tags:</b>
        <a class="article-tag-none-link" href="/tags/springCloud/" rel="tag">springCloud</a>
      
    </div>
    
    
  </div>
</article>

  
<nav id="article-nav" class="article-nav">
  
    <a href="/2020/10/01/springcloud%E4%B9%8Bstream%E6%B6%88%E6%81%AF%E9%A9%B1%E5%8A%A8/" id="article-nav-newer" class="article-nav-link-wrap newer">
      <strong class="article-nav-caption">Newer</strong>
      <div class="article-nav-title">
        
          springcloud之stream消息驱动
        
      </div>
    </a>
  
  
    <a href="/2020/09/29/springcloud%E4%B9%8Bconfig%E5%88%86%E5%B8%83%E5%BC%8F%E9%85%8D%E7%BD%AE%E4%B8%AD%E5%BF%83/" id="article-nav-older" class="article-nav-link-wrap older">
      <strong class="article-nav-caption">Older</strong>
      <div class="article-nav-title">
        
          springcloud之config分布式配置中心
        
      </div>
    </a>
  
</nav>






    </div>
  </div>
  




<div id="settings-container">
  <div id="dark-mode">dark</div>
  <div id="sans-font">sans</div>
</div>
<script type="text/javascript">
let d=document,r=d.documentElement.style,f=r.setProperty.bind(r),l=localStorage,s=l.getItem('s')||(window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches),n=l.getItem('n'),m=d.getElementById("dark-mode"),b=()=>{f('--bg-color','#fafafa');f('--code-bg-color','#f4f4f4');f('--text-color','#212121');f('--secondary-color','#808080');f('--tertiary-color','#b0b0b0');f('--link-color','#b5c8cf');f('--link-hover-color','#618794');f('--link-bg-color','#dae4e7');f('--selection-color','#dae4e7');m.innerHTML="dark"},c=()=>{f('--bg-color','#212121');f('--code-bg-color','#292929');f('--text-color','#fff');f('--secondary-color','#c0c0c0');f('--tertiary-color','#6e6e6e');f('--link-color','#4d6b75');f('--link-hover-color','#96b1bb');f('--link-bg-color','#5d828e');f('--selection-color','#acc1c9');m.innerHTML="light"},o=d.getElementById("sans-font"),e=()=>{f('--body-stack','"Lora", "Georgia", "Times New Roman", serif');o.innerHTML="sans"},g=()=>{f('--body-stack','"Lato", "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", "Verdana", sans-serif');o.innerHTML="serif"};m.onclick=()=>{if(s==2){s=1;l.setItem('s',s);c()}else{s=2;l.setItem('s',s);b()}};o.onclick=()=>{if(n==2){n=1;l.setItem('n',n);g()}else{n=2;l.setItem('n',n);e()}};if(!s){s=2;l.setItem('s',2)};if(s==1){c()};if(!n){n=2;l.setItem('n',2)};if(n==1){g()};
</script>




</body>
</html>
